package org.pool;

import org.pool.conf.DBConfig;
import org.pool.connection.PooledConnection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;

/**
 * Created with IntelliJ IDEA.
 * Description: 默认的实现池
 * User: zpr
 * Date: 2018-04-17
 * Time: 12:38
 */
public class DefaultPool implements IPool{
    //多线程考虑
    private Vector<PooledConnection> pooledConnectionVector = new Vector<>();
    public static  String jdbcUrl;
    public static  String jdbcUserName;
    public static  String jdbcPassWord;
    //数据连接池 初始化大小
    public static  int initCount ;
    //连接池不足时，增长时的 步进值
    public static  int step;
    //数据连接池 最大值
    public static  int maxCount;

    public DefaultPool() {
        init();
        try{
            Class.forName(DBConfig.jdbcDriver);
        }catch (Exception e){
            e.printStackTrace();;
        }
        createPooledConnection(initCount);
    }

    /**
     *  初始化配置文件
     */
    private void init() {
        jdbcUrl = DBConfig.jdbcUrl;
        jdbcUserName = DBConfig.jdbcUserName;
        jdbcPassWord = DBConfig.jdbcPassWord;
        initCount = DBConfig.initCount;
        step = DBConfig.step;
        maxCount = DBConfig.maxCount;
    }

    @Override
    public PooledConnection getPooledConnection() {
        if(pooledConnectionVector.size()<1){
            throw new RuntimeException("数据库连接池初始化失败");
        }
        PooledConnection pooledConnection = null;
        try{
            pooledConnection = getRealConnectionFromPool();
            //标识 数据库连接池已满，按照步长 增加
            while(pooledConnection == null){
                createPooledConnection(step);
                //重新获取真实 连接
                pooledConnection = getRealConnectionFromPool();
                return pooledConnection;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return pooledConnection;
    }

    @Override
    public void createPooledConnection(int count) {
        if(pooledConnectionVector.size()>maxCount
                || pooledConnectionVector.size()+count>maxCount){
            throw new RuntimeException("连接池已满");
        }
        for(int i=0 ; i<count ; i++){
            try{
                Connection connection = DriverManager.getConnection(jdbcUrl, jdbcUserName, jdbcPassWord);
                PooledConnection pooledConnection = new PooledConnection(connection,false);
                pooledConnectionVector.add(pooledConnection);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    private synchronized PooledConnection getRealConnectionFromPool() throws SQLException {
        for(PooledConnection pooledConnection : pooledConnectionVector){
            if(!pooledConnection.isBusy()){
                //验证 连接 超时 时间
                if(pooledConnection.getConnection().isValid(3000)){
                    pooledConnection.setBusy(true);
                    return pooledConnection;
                }else{
                    Connection connection = DriverManager.getConnection(jdbcUrl, jdbcUserName, jdbcPassWord);
                    pooledConnection.setConnection(connection);
                    pooledConnection.setBusy(true);
                    return pooledConnection;
                }
            }
        }
        return null;
    }
}
